/**
 * 播放列表相关API - 数据库优先，统一使用SET同步
 * 
 * 新架构说明:
 * - 所有操作: 先调用云函数操作数据库 → 成功后发送MQTT SET指令同步完整播放列表
 * - 查询操作: 直接从数据库获取
 * 
 * MQTT协议说明:
 * - 主题路径: /SANDART001/{设备SN}/command
 * - 消息格式: {"cmd": "playlist", "data": {"action": "set", "patterns": [...]}}
 * - 只使用SET指令，确保设备端播放列表与数据库完全一致
 */

// 导入云对象
const sandart = uniCloud.importObject('sandart')
import mqttApi from './my-mqtt.js'
import patternApi from './pattern.js'

/**
 * 将 pattern_id 转换为 pattern_file
 * @param {string} patternId - 图案ID
 * @returns {Promise<string>} pattern_file 路径
 */
const convertPatternIdToFile = async (patternId) => {
	try {
		console.log(`[PLAYLIST] 转换图案ID ${patternId} 为文件路径`);
		const res = await patternApi.getPatternDetail(patternId);
		if (res.errCode === 0 && res.data) {
			const patternFile = res.data.pattern_file || res.data.file_name || patternId;
			console.log(`[PLAYLIST] 图案ID ${patternId} 转换为文件路径: ${patternFile}`);
			return patternFile;
		}
	} catch (error) {
		console.warn(`[PLAYLIST] 获取图案 ${patternId} 的文件路径失败:`, error);
	}
	// 如果获取失败，返回原始ID（可能本身就是文件路径）
	return patternId;
};

/**
 * 处理图案参数，统一转换为文件路径字符串（内存优化版本）
 * @param {string|object} pattern - 图案参数
 * @param {string} operation - 操作类型 'add' 或 'remove'
 * @returns {Promise<string>} 图案文件路径或文件名
 */
const processPattern = async (pattern, operation = 'add') => {
	let filePath = '';
	
	if (typeof pattern === 'string') {
		// 如果是字符串，判断是patternId还是文件路径
		if (pattern.includes('/') || pattern.includes('.')) {
			// 包含路径分隔符或扩展名，当作文件路径处理
			filePath = pattern;
		} else {
			// 可能是patternId，尝试转换为文件路径
			filePath = await convertPatternIdToFile(pattern);
		}
	} else if (pattern && typeof pattern === 'object') {
		// 对象格式，优先使用pattern_file，其次file_name
		filePath = pattern.pattern_file || pattern.file_name || pattern.fileName || pattern.patternFile;
		
		// 如果没有文件信息但有pattern_id，尝试转换
		if (!filePath && pattern.pattern_id) {
			filePath = await convertPatternIdToFile(pattern.pattern_id);
		}
	}
	
	if (!filePath) {
		console.warn('[PLAYLIST] 无法从图案参数中提取文件信息:', pattern);
		filePath = String(pattern); // 兜底处理
	}
	
	// 根据操作类型返回不同的格式
	if (operation === 'remove') {
		// REMOVE 操作：提取文件名
		const fileName = filePath.includes('/') 
			? filePath.substring(filePath.lastIndexOf('/') + 1)
			: filePath;
		console.log(`[PLAYLIST] 处理REMOVE图案参数: ${JSON.stringify(pattern)} -> ${fileName}`);
		return fileName;
	} else {
		// ADD/SET 等操作：返回完整路径
		console.log(`[PLAYLIST] 处理ADD图案参数: ${JSON.stringify(pattern)} -> ${filePath}`);
		return filePath;
	}
};

/**
 * 从完整路径中提取文件名
 * @param {string} fullPath - 完整路径或文件名
 * @returns {string} 文件名部分
 */
const extractFileNameFromPath = (fullPath) => {
	if (!fullPath || typeof fullPath !== 'string') {
		return '';
	}
	
	// 如果包含 /，提取最后一部分
	if (fullPath.includes('/')) {
		const lastSlashIndex = fullPath.lastIndexOf('/');
		return fullPath.substring(lastSlashIndex + 1);
	}

	// 如果没有 /，直接返回
	return fullPath;
};

/**
 * 同步播放列表到设备
 * 从数据库获取完整播放列表，通过MQTT SET指令推送到设备
 * 
 * @param {string} deviceSn - 设备SN（用于MQTT通信和数据库查询）
 * @returns {Promise<boolean>} 是否同步成功
 */
const syncPlaylistToDevice = async (deviceSn, options = {}) => {
	try {
		if (!deviceSn) {
			console.warn(`[PLAYLIST] deviceSn 参数为空，无法同步`)
			return false
		}
		
		// 默认配置
		const {
			usePagination = true,  // 默认启用分页
			pageSize = 10,         // 每页10个图案
			delayMs = 100          // 每页延迟100ms
		} = options
		
		console.log(`[PLAYLIST] 同步播放列表 - deviceSn=${deviceSn}, 分页=${usePagination}`)
		
		// 1. 从数据库获取完整播放列表（只使用 deviceSn）
		const apiResult = await sandart.getPlaylist({
			sn: deviceSn
		})
		
		if (apiResult.errCode !== 0 || !apiResult.data) {
			console.warn(`[PLAYLIST] 获取播放列表失败，无法同步到设备`, apiResult)
			return false
		}
		
		const patterns = apiResult.data.patterns || []
		
		// 2. 提取文件路径字符串数组
		const patternFiles = patterns.map(p => p.file_name)
		
		console.log(`[PLAYLIST] 播放列表共 ${patternFiles.length} 个图案`)
		
		// 3. 通过MQTT SET指令推送完整播放列表（始终使用分页方式）
		console.log(`[PLAYLIST] 使用分页方式同步 (每页${pageSize}个，延迟${delayMs}ms)`)
		const success = await mqttApi.setPlaylist(deviceSn, patternFiles, pageSize)
		
		if (success) {
			console.log(`[PLAYLIST] 播放列表同步成功`)
		} else {
			console.warn(`[PLAYLIST] 播放列表同步失败`)
		}
		
		return success
	} catch (error) {
		console.error('[PLAYLIST] 同步播放列表到设备失败:', error)
		return false
	}
}

/**
 * 发送播放列表命令到指定设备
 * @deprecated 仅保留用于特殊场景，常规操作请使用 syncPlaylistToDevice
 */
const sendPlaylistCommand = async (deviceSn, action, data = {}) => {
	try {
		let result;
		
		switch (action) {
			case 'set':
				// 设置播放列表（覆盖）
				result = await mqttApi.setPlaylist(deviceSn, data.patterns || []);
				break;
			default:
				// 其他命令
				const message = {
					cmd: "playlist",
					data: {
						action: action,
						...data
					}
				};
				result = await mqttApi.sendCommand(deviceSn, message.cmd, message.data);
				break;
		}
		
		console.log(`[PLAYLIST] 向设备 ${deviceSn} 发送playlist命令:`, { action, data, result });
		return true;
	} catch (error) {
		console.error('[PLAYLIST] 发送播放列表命令失败:', error);
		return false;
	}
};

export default {
	/**
	 * 立即播放指定图案
	 * 
	 * 逻辑说明:
	 * - 多个图案: 清空播放列表，按顺序添加新图案，同步完整播放列表
	 * - 单个图案: 将图案插入到播放列表第一位，同步播放列表，并调用MQTT play接口立即播放
	 * 
	 * @param {object} params - 参数对象
	 * @param {string|string[]} params.deviceSn - 设备SN或SN数组（推荐使用）
	 * @param {string|string[]} params.deviceId - 设备ID或ID数组（向后兼容）
	 * @param {string[]|object[]} params.patterns - 图案列表，支持多种格式
	 * @param {string[]} params.patternIds - 图案ID列表（向后兼容）
	 * @param {string[]} params.patternFiles - 图案文件列表（向后兼容）
	 */
	async playNow(params) {
		try {
			const { deviceId, deviceSn, patterns, patternIds, patternFiles } = params
			const devices = deviceSn || deviceId
			const deviceList = Array.isArray(devices) ? devices : [devices]
			
			// 统一处理patterns参数，支持多种格式
			let patternList = patterns || patternFiles || patternIds || []
			if (!Array.isArray(patternList)) {
				patternList = [patternList]
			}
			
			const isSinglePattern = patternList.length === 1
			console.log(`[PLAYLIST] 立即播放 - ${isSinglePattern ? '单个' : '多个'}图案`, { 
				deviceList, 
				patternCount: patternList.length 
			})
			
			const results = []
			
			// 为每个设备执行操作
			for (const deviceIdentifier of deviceList) {
				try {
					if (isSinglePattern) {
						// 单个图案: 先检查是否已在播放列表中
						console.log(`[PLAYLIST] 单个图案模式 - 检查图案是否已在播放列表中`)
						
						// 1. 获取当前播放列表
						const playlistResult = await sandart.getPlaylist({
							sn: deviceIdentifier
						})
						
						let fileName = null
						let patternExists = false
						
						if (playlistResult.errCode === 0 && playlistResult.data) {
							const patterns = playlistResult.data.patterns || []
							// 将 patternList[0] 转换为文件路径进行比较
							const targetFile = await processPattern(patternList[0], 'add')
							const targetFileName = extractFileNameFromPath(targetFile)
							
							// 检查图案是否已存在
							const existingPattern = patterns.find(p => {
								const existingFileName = extractFileNameFromPath(p.file_name)
								return existingFileName === targetFileName
							})
							
							if (existingPattern) {
								patternExists = true
								fileName = existingPattern.file_name
								console.log(`[PLAYLIST] 图案已在播放列表中，直接播放: ${fileName}`)
							}
						}
						
						// 2. 如果图案不存在，则添加到播放列表
						if (!patternExists) {
							console.log(`[PLAYLIST] 图案不在播放列表中，插入到第一位`)
							const apiResult = await sandart.addPatternToPlaylist({
								sn: deviceSn ? deviceIdentifier : undefined,
								deviceId: deviceId ? deviceIdentifier : undefined,
								patternId: patternList[0],
								sortOrder: 1  // 插入到第一位
							})
							
							if (apiResult.errCode !== 0) {
								throw new Error(apiResult.errMsg || '添加图案失败')
							}
							
							fileName = apiResult.data?.pattern?.file_name
							
							// 同步完整播放列表到设备
							await syncPlaylistToDevice(deviceIdentifier)
						}
						
						// 3. 调用MQTT playDrawing立即播放
						console.log(`[PLAYLIST] 调用MQTT playDrawing立即播放图案: ${fileName}`)
						await mqttApi.playDrawing(deviceIdentifier, fileName)
						
						results.push({
							deviceSn: deviceIdentifier,
							success: true,
							mode: 'single',
							patternExists: patternExists,
							fileName: fileName
						})
						
						console.log(`[PLAYLIST] 设备 ${deviceIdentifier} 单图案播放成功 (${patternExists ? '已存在' : '新添加'})`)
					} else {
						// 多个图案: 清空并添加新列表
						console.log(`[PLAYLIST] 多图案模式 - 清空并添加 ${patternList.length} 个图案`)
						
						const apiResult = await sandart.playNow({
							sn: deviceSn ? deviceIdentifier : undefined,
							deviceId: deviceId ? deviceIdentifier : undefined,
							patternIds: patternList
						})
						
						if (apiResult.errCode !== 0) {
							throw new Error(apiResult.errMsg || '立即播放失败')
						}
						
						// 从云函数返回结果中获取成功添加的图案详情
						const resultData = Array.isArray(apiResult.data) ? apiResult.data[0] : apiResult.data
						
						// 同步完整播放列表到设备（只需要 deviceSn）
						await syncPlaylistToDevice(deviceIdentifier)
						
						// 调用MQTT playDrawing立即播放第一个图案，传入file_name
						const addedPatternDetails = resultData?.addedPatternDetails || []
						const firstPatternFileName = addedPatternDetails.length > 0 ? addedPatternDetails[0].file_name : null
						console.log(`[PLAYLIST] 调用MQTT playDrawing立即播放第一个图案: ${firstPatternFileName}`)
						await mqttApi.playDrawing(deviceIdentifier, firstPatternFileName)
						
						results.push({
							deviceSn: deviceIdentifier,
							success: true,
							mode: 'multiple',
							addedCount: resultData?.added_count,
							skippedCount: resultData?.skipped_count
						})
						
						console.log(`[PLAYLIST] 设备 ${deviceIdentifier} 多图案播放列表更新成功`)
					}
				} catch (error) {
					console.error(`[PLAYLIST] 设备 ${deviceIdentifier} 播放失败:`, error)
					results.push({
						deviceSn: deviceIdentifier,
						success: false,
						error: error.message
					})
				}
			}
			
			const allSuccess = results.every(r => r.success)
			
			return {
				errCode: allSuccess ? 0 : 500,
				errMsg: allSuccess ? '播放成功' : '部分设备播放失败',
				data: results
			}
		} catch (error) {
			console.error('[PLAYLIST] 立即播放失败:', error)
			return {
				errCode: 500,
				errMsg: '立即播放失败: ' + error.message,
				data: null
			}
		}
	},

	/**
	 * 批量添加图案到播放列表末尾
	 * 新流程:
	 * 1. 调用云函数 batchAddPatternsToEnd (添加到数据库)
	 * 2. 成功后发送MQTT SET指令同步完整播放列表
	 * 
	 * @param {object} params - 参数对象
	 * @param {string|string[]} params.deviceSn - 设备SN或SN数组（推荐使用）
	 * @param {string|string[]} params.deviceId - 设备ID或ID数组（向后兼容）
	 * @param {string[]|object[]} params.patterns - 图案列表
	 * @param {string[]} params.patternIds - 图案ID列表（向后兼容）
	 */
	async batchAddPatternsToEnd(params) {
		try {
			const { deviceId, deviceSn, patterns, patternIds } = params
			const devices = deviceSn || deviceId
			const deviceList = Array.isArray(devices) ? devices : [devices]
			
			// 统一处理patterns参数
			let patternList = patterns || patternIds || []
			if (!Array.isArray(patternList)) {
				patternList = [patternList]
			}
			
			console.log('[PLAYLIST] 批量添加 - 开始处理', { deviceList, patternList })
			
			const results = await Promise.all(deviceList.map(async (deviceIdentifier) => {
				try {
					// 步骤1: 调用云函数更新数据库（云函数已支持通过sn查询）
					console.log(`[PLAYLIST] 调用云函数 batchAddPatternsToEnd: deviceSn=${deviceIdentifier}`)
					const apiResult = await sandart.batchAddPatternsToEnd({
						sn: deviceSn ? deviceIdentifier : undefined,
						deviceId: deviceId ? deviceIdentifier : undefined,
						patternIds: patternList
					})
					
					if (apiResult.errCode !== 0) {
						throw new Error(apiResult.errMsg || '数据库操作失败')
					}
					
					// 步骤2: 数据库更新成功，同步完整播放列表到设备（使用SET指令）
					console.log(`[PLAYLIST] 数据库更新成功，同步完整播放列表到设备`)
					await syncPlaylistToDevice(deviceIdentifier)
					
					// 提取返回数据
					const results = Array.isArray(apiResult.data) ? apiResult.data : [apiResult.data]
					const successResult = results.find(r => r && (r.success || r.added_count !== undefined)) || {}
					
					console.log(`[PLAYLIST] 设备 ${deviceIdentifier} 批量添加成功`)
					return { 
						deviceSn: deviceIdentifier, 
						success: true,
						addedCount: successResult?.added_count || 0,
						skippedCount: successResult?.skipped_count || 0
					}
				} catch (error) {
					console.error(`[PLAYLIST] 设备 ${deviceIdentifier} 批量添加失败:`, error)
					return { 
						deviceSn: deviceIdentifier, 
						success: false, 
						error: error.message 
					}
				}
			}))
			
			const allSuccess = results.every(r => r.success)
			
			return {
				errCode: allSuccess ? 0 : 500,
				errMsg: allSuccess ? '添加成功' : '部分设备添加失败',
				data: results
			}
		} catch (error) {
			console.error('[PLAYLIST] 批量添加图案失败:', error)
			return {
				errCode: 500,
				errMsg: '批量添加图案失败: ' + error.message,
				data: null
			}
		}
	},

	/**
	 * 添加单个图案到播放列表
	 * 新流程:
	 * 1. 如果sortOrder=1，调用playNow (立即播放)
	 * 2. 否则调用addPatternToPlaylist (添加到数据库) + 发送MQTT SET指令同步
	 * 
	 * @param {object} params - 参数对象
	 * @param {string} params.deviceSn - 设备SN
	 * @param {string} params.deviceId - 设备ID（向后兼容）
	 * @param {string} params.patternId - 图案ID
	 * @param {number} params.sortOrder - 排序（1=立即播放，其他=添加到列表）
	 */
	async addPattern(params) {
		try {
			const { deviceId, deviceSn, patternId, sortOrder } = params
			const deviceIdentifier = deviceSn || deviceId
			
			console.log(`[PLAYLIST] 添加单个图案 - deviceId=${deviceIdentifier}, patternId=${patternId}, sortOrder=${sortOrder}`)
			
			// 如果sortOrder为1，使用playNow立即播放
			if (sortOrder === 1) {
				return await this.playNow({
					deviceSn: deviceSn,
					deviceId: deviceId,
					patternIds: [patternId]
				})
			}
			
			// 否则添加到播放列表
			// 步骤1: 调用云函数添加到数据库
			const apiResult = await sandart.addPatternToPlaylist({
				sn: deviceSn,
				deviceId: deviceId ? deviceIdentifier : undefined,
				patternId: patternId,
				sortOrder: sortOrder
			})
			
			if (apiResult.errCode !== 0) {
				throw new Error(apiResult.errMsg || '数据库操作失败')
			}
			
			// 步骤2: 同步完整播放列表（使用SET指令）
			console.log('[PLAYLIST] 单个图案添加成功，同步完整播放列表')
			await syncPlaylistToDevice(deviceIdentifier)
			
			return {
				errCode: 0,
				errMsg: '添加成功',
				data: { 
					deviceSn: deviceIdentifier, 
					patternId,
					pattern: apiResult.data?.pattern
				}
			}
		} catch (error) {
			console.error('[PLAYLIST] 添加图案失败:', error)
			return {
				errCode: 500,
				errMsg: '添加图案失败: ' + error.message,
				data: null
			}
		}
	},

	/**
	 * 更新播放模式
	 * 注意：此功能可能需要配合其他MQTT命令实现
	 * 
	 * @param {object} params - 参数对象
	 * @param {string} params.deviceSn - 设备SN
	 * @param {string} params.deviceId - 设备ID（向后兼容）
	 * @param {string} params.playMode - 播放模式：'0'=顺序，'1'=随机，'2'=单曲循环
	 */
	async updatePlayMode(params) {
		try {
			const { deviceId, deviceSn, playMode } = params
			const deviceIdentifier = deviceSn || deviceId
			
			const modeMap = {
				'0': 'sequential',
				'1': 'random',
				'2': 'repeat_one'
			}
			const mode = modeMap[playMode] || 'sequential'
			
			// 注意：播放模式可能需要通过其他MQTT命令设置
			// 这里暂时使用playlist命令，可能需要根据实际协议调整
			console.warn('[PLAYLIST] 播放模式设置可能需要使用其他MQTT命令')
			
			const success = await sendPlaylistCommand(deviceIdentifier, 'set_mode', { mode })
			
			return {
				errCode: success ? 0 : 500,
				errMsg: success ? '播放模式更新成功' : '播放模式更新失败',
				data: { deviceSn: deviceIdentifier, playMode, mode }
			}
		} catch (error) {
			console.error('[PLAYLIST] 更新播放模式失败:', error)
			return {
				errCode: 500,
				errMsg: '更新播放模式失败',
				data: null
			}
		}
	},

	/**
	 * 获取播放列表
	 * 新流程: 直接从数据库获取，支持通过 deviceId 或 deviceSn 查询
	 * 
	 * @param {object} params - 参数对象
	 * @param {string} params.deviceSn - 设备SN（推荐使用）
	 * @param {string} params.deviceId - 设备ID（可选，与deviceSn二选一）
	 */
	async getPlaylist(params) {
		try {
			const { deviceId, deviceSn } = params
			
			if (!deviceId && !deviceSn) {
				throw new Error('deviceId 和 deviceSn 至少需要提供一个')
			}
			
			console.log(`[PLAYLIST] 获取播放列表 - deviceId=${deviceId}, deviceSn=${deviceSn}`)
			
			// 调用云函数从数据库获取（云函数已支持通过sn查询）
			// 只传递有值的参数，避免 undefined 干扰查询
			const queryParams = {}
			if (deviceId) queryParams.deviceId = deviceId
			if (deviceSn) queryParams.sn = deviceSn
			
			console.log(`[PLAYLIST] 云函数查询参数:`, queryParams)
			
			const apiResult = await sandart.getPlaylist(queryParams)
			
			console.log(`[PLAYLIST] 云函数返回:`, {
				errCode: apiResult.errCode,
				errMsg: apiResult.errMsg,
				hasData: !!apiResult.data,
				patternsCount: apiResult.data?.patterns?.length || 0
			})
			
			if (apiResult.errCode !== 0) {
				throw new Error(apiResult.errMsg || '获取失败')
			}
			
			return {
				errCode: 0,
				errMsg: '获取播放列表成功',
				data: apiResult.data
			}
		} catch (error) {
			console.error('[PLAYLIST] 获取播放列表失败:', error)
			return {
				errCode: 500,
				errMsg: '获取播放列表失败: ' + error.message,
				data: null
			}
		}
	},

	/**
	 * 推送播放列表到设备
	 * 从数据库获取播放列表，然后通过MQTT推送到设备
	 * 
	 * @param {object} params - 参数对象
	 * @param {string} params.deviceSn - 设备SN（推荐使用）
	 * @param {string} params.deviceId - 设备ID（可选）
	 * @returns {Promise<object>} 推送结果
	 */
	async syncPlaylistToDevice(params) {
		try {
			const { deviceId, deviceSn } = params
			
			if (!deviceId && !deviceSn) {
				throw new Error('deviceId 和 deviceSn 至少需要提供一个')
			}
			
			console.log(`[PLAYLIST] 推送播放列表到设备 - deviceSn=${deviceSn}`)
			
			// 1. 从数据库获取播放列表
			const playlistResult = await this.getPlaylist({ deviceId, deviceSn })
			
			if (playlistResult.errCode !== 0 || !playlistResult.data) {
				throw new Error('获取播放列表失败')
			}
			
			const patterns = playlistResult.data.patterns || []
			console.log(`[PLAYLIST] 获取到 ${patterns.length} 个图案`, patterns)
			
			if (patterns.length === 0) {
				console.log(`[PLAYLIST] 播放列表为空，无需推送`)
				return {
					errCode: 0,
					errMsg: '播放列表为空',
					data: { patternCount: 0 }
				}
			}
			
			// 2. 提取文件名字符串数组（只使用 file_name）
			const patternFiles = patterns.map(p => p.file_name || String(p))
			
			console.log(`[PLAYLIST] 推送 ${patternFiles.length} 个图案到设备 ${deviceSn}:`, patternFiles)
			
			// 3. 通过MQTT推送到设备
			const deviceIdentifier = deviceSn || deviceId
			const success = await mqttApi.setPlaylist(deviceIdentifier, patternFiles)
			
			if (success) {
				console.log(`[PLAYLIST] 播放列表推送成功`)
				return {
					errCode: 0,
					errMsg: '播放列表推送成功',
					data: {
						deviceSn: deviceIdentifier,
						patternCount: patternFiles.length,
						patterns: patternFiles
					}
				}
			} else {
				throw new Error('MQTT推送失败')
			}
		} catch (error) {
			console.error('[PLAYLIST] 推送播放列表失败:', error)
			return {
				errCode: 500,
				errMsg: '推送播放列表失败: ' + error.message,
				data: null
			}
		}
	},

	/**
	 * 清空播放列表
	 * 新流程: 调用云函数清空数据库 + 发送MQTT SET指令同步空列表
	 * 
	 * @param {object} params - 参数对象
	 * @param {string} params.deviceSn - 设备SN（推荐使用）
	 * @param {string} params.deviceId - 设备ID（向后兼容）
	 */
	async clearPlaylist(params) {
		try {
			const { deviceId, deviceSn } = params
			const deviceIdentifier = deviceSn || deviceId
			
			console.log(`[PLAYLIST] 清空播放列表 - deviceSn=${deviceSn}, deviceId=${deviceId}`)
			
			// 步骤1: 调用云函数清空数据库（云函数已支持通过sn查询）
			const apiResult = await sandart.clearPlaylist({
				deviceId: deviceId,
				sn: deviceSn
			})
			
			if (apiResult.errCode !== 0) {
				throw new Error(apiResult.errMsg || '数据库操作失败')
			}
			
			// 步骤2: 同步空播放列表到设备（使用SET指令）
			console.log('[PLAYLIST] 数据库清空成功，同步空列表到设备')
			await syncPlaylistToDevice(deviceIdentifier)
			
			return {
				errCode: 0,
				errMsg: '清空播放列表成功',
				data: { deviceSn: deviceIdentifier }
			}
		} catch (error) {
			console.error('[PLAYLIST] 清空播放列表失败:', error)
			return {
				errCode: 500,
				errMsg: '清空播放列表失败: ' + error.message,
				data: null
			}
		}
	},

	/**
	 * 从播放列表移除图案
	 * 新流程: 删除数据库 + 发送MQTT SET指令同步完整播放列表
	 * 
	 * @param {object} params - 参数对象
	 * @param {string} params.deviceSn - 设备SN
	 * @param {string} params.deviceId - 设备ID（向后兼容）
	 * @param {string[]} params.patternIds - 要移除的图案ID列表
	 */
	async removePatterns(params) {
		try {
			const { deviceId, deviceSn, patternIds } = params
			const deviceIdentifier = deviceSn || deviceId
			
			if (!patternIds || patternIds.length === 0) {
				return {
					errCode: 400,
					errMsg: '图案ID列表不能为空',
					data: null
				}
			}
			
			console.log(`[PLAYLIST] 批量移除图案 - deviceId=${deviceIdentifier}, 数量=${patternIds.length}`)
			
			// 循环删除每个图案（只操作数据库）
			const results = []
			for (const patternId of patternIds) {
				try {
					const apiResult = await sandart.removePatternFromPlaylist({
						deviceId: deviceIdentifier,
						sn: deviceSn,
						patternId: patternId
					})
					
					results.push({
						patternId,
						success: apiResult.errCode === 0,
						message: apiResult.errMsg
					})
				} catch (error) {
					results.push({
						patternId,
						success: false,
						message: error.message
					})
				}
			}
			
			const successCount = results.filter(r => r.success).length
			console.log(`[PLAYLIST] 批量移除完成: 成功${successCount}个，失败${results.length - successCount}个`)
			
			// 如果有成功删除的，同步完整播放列表到设备
			if (successCount > 0) {
				console.log('[PLAYLIST] 同步完整播放列表到设备')
				await syncPlaylistToDevice(deviceIdentifier)
			}
			
			return {
				errCode: successCount > 0 ? 0 : 500,
				errMsg: successCount === results.length ? '批量移除成功' : `部分移除失败 (${successCount}/${results.length})`,
				data: { 
					deviceSn: deviceIdentifier, 
					results 
				}
			}
		} catch (error) {
			console.error('[PLAYLIST] 批量移除图案失败:', error)
			return {
				errCode: 500,
				errMsg: '批量移除图案失败: ' + error.message,
				data: null
			}
		}
	},

	/**
	 * 移除单个图案（兼容方法）
	 * 新流程: 删除数据库 + 发送MQTT SET指令同步完整播放列表
	 * 
	 * @param {object} params - 参数对象
	 * @param {string} params.deviceSn - 设备SN（推荐使用）
	 * @param {string} params.deviceId - 设备ID（向后兼容）
	 * @param {string} params.patternId - 要移除的图案ID
	 */
	async removePattern(params) {
		try {
			const { deviceId, deviceSn, patternId } = params
			const deviceIdentifier = deviceSn || deviceId
			
			console.log(`[PLAYLIST] 移除图案 - deviceSn=${deviceSn}, deviceId=${deviceId}, patternId=${patternId}`)
			
			// 步骤1: 调用云函数删除数据库（云函数已支持通过sn查询）
			const apiResult = await sandart.removePatternFromPlaylist({
				deviceId: deviceId,
				sn: deviceSn,
				patternId: patternId
			})
			
			if (apiResult.errCode !== 0) {
				throw new Error(apiResult.errMsg || '删除失败')
			}
			
			// 步骤2: 同步完整播放列表到设备（使用SET指令）
			console.log(`[PLAYLIST] 图案移除成功，同步完整播放列表`)
			await syncPlaylistToDevice(deviceIdentifier)
			
			return {
				errCode: 0,
				errMsg: '移除图案成功',
				data: { 
					deviceSn: deviceIdentifier, 
					patternId,
					removedPattern: apiResult.data?.removed_pattern
				}
			}
		} catch (error) {
			console.error('[PLAYLIST] 移除单个图案失败:', error)
			return {
				errCode: 500,
				errMsg: '移除图案失败: ' + error.message,
				data: null
			}
		}
	},
	
	/**
	 * 重新排序播放列表中的图案
	 * 新流程: 更新数据库排序 + 发送MQTT SET指令同步完整播放列表
	 * 
	 * @param {object} params - 参数对象
	 * @param {string} params.deviceSn - 设备SN（推荐使用）
	 * @param {string} params.deviceId - 设备ID（向后兼容）
	 * @param {Array} params.patternOrders - 图案排序数组 [{patternId, sortOrder}]
	 * @returns {Promise<object>} 排序结果
	 */
	async reorderPatterns(params) {
		try {
			const { deviceId, deviceSn, patternOrders } = params
			const deviceIdentifier = deviceSn || deviceId
			
			if (!patternOrders || !Array.isArray(patternOrders)) {
				throw new Error('patternOrders参数必须是数组')
			}
			
		console.log(`[PLAYLIST] 重新排序 - deviceSn=${deviceSn}, patterns=${patternOrders.length}个`)
		
		// 步骤1: 调用云函数更新数据库中的排序
		// 构建参数对象，只传递有效的设备标识符
		const cloudParams = {
			patternOrders: patternOrders
		}
		if (deviceSn) {
			cloudParams.sn = deviceSn
		} else if (deviceId) {
			cloudParams.deviceId = deviceId
		}
		
		const apiResult = await sandart.reorderPatternsInPlaylist(cloudParams);
		
		if (apiResult.errCode !== 0) {
			throw new Error(apiResult.errMsg || '更新排序失败')
		}
		
		// 步骤2: 同步完整播放列表到设备（使用SET指令）
			console.log(`[PLAYLIST] 排序更新成功，同步完整播放列表`)
			await syncPlaylistToDevice(deviceIdentifier)
			
			return {
				errCode: 0,
				errMsg: '排序更新成功',
				data: {
					deviceSn: deviceIdentifier,
					patterns: apiResult.data?.patterns
				}
			}
		} catch (error) {
			console.error('[PLAYLIST] 重新排序失败:', error)
			return {
				errCode: 500,
				errMsg: '排序更新失败: ' + error.message,
				data: null
			}
		}
	}
}

